package it.infodea.tapestrydea.components.livegrid;

import java.util.List;

import org.apache.tapestry5.Block;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.PropertyOverrides;
import org.apache.tapestry5.RenderSupport;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.beaneditor.BeanModel;
import org.apache.tapestry5.beaneditor.PropertyModel;
import org.apache.tapestry5.corelib.components.Any;
import org.apache.tapestry5.corelib.components.Form;
import org.apache.tapestry5.corelib.components.PropertyEditor;
import org.apache.tapestry5.corelib.components.Submit;
import org.apache.tapestry5.grid.GridModel;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.ioc.annotations.Inject;

@IncludeJavaScriptLibrary({"LGridInsertRow.js","../Simulator.js"})
public class LGridInsertRow {

	public static final String ADD_ROW_EVENT = "addRow";

	@Parameter
	@Property(read=true)
	private String zone;
	
//	@Parameter
//	private Class<?> rowClass;

    /**
     * Object that provides access to the bean and data models used to render the Grid.
     */
    @Parameter(value = "componentResources.container")
    private GridModel gridModel;

    /**
     * If true, then the CSS class on each &lt;TH&gt; element will be omitted, which can reduce the amount of output
     * from the component overall by a considerable amount. Leave this as false, the default, when you are leveraging
     * the CSS to customize the look and feel of particular columns.
     */
//    @Parameter
//    private boolean lean;

    /**
     * Where to look for informal parameter Blocks used to override column headers.  The default is to look for such
     * overrides in the GridColumns component itself, but this is usually overridden.
     */
    @Parameter("this")
    private PropertyOverrides overrides;

    @Component
    private Any rowForm;
    
	@SuppressWarnings("unused")
	@Component(parameters = { "object=instance", "property=prop:columnName", "model=model" })
	private PropertyEditor editor;
    
    @Component(parameters = {"zone=inherit:zone"})
    @Property(write=false)
    private Form addRowForm;

//    @Component(parameters={"id=literal:addRowButton"})
//    private Any addRowButton;
    
    @Component
    private Submit submitDelegate;
    
//    @Inject
//    private Messages messages;

    @Inject
    private Block standardInputCell;

    @Inject
    private Block lGridRemoveCell;
    
    @Inject
    private Block delegateInputCell;
    
    @Inject
    private Block emptyCell;
    
    /**
     * Optional output parameter that stores the current column index.
     */
    @SuppressWarnings("unused")
    @Parameter
    @Property
    private int index;

//    /**
//     * Caches the index of the last column.
//     */
//    private int lastColumnIndex;

    @Property(write = false)
    private PropertyModel columnModel;

    @Inject
    private ComponentResources resources;

    @Inject
    private RenderSupport support;
    
    @Parameter
	private Object instance;

    void setupRender() {
    	//if(instance == null)instance = getModel().newInstance();
//		lastColumnIndex = gridModel.getDataModel().getPropertyNames().size() - 1;
	}

    void afterRender(){
    	List<String> columnNames = gridModel.getDataModel().getPropertyNames();
    	StringBuffer params = new StringBuffer("[");
    	for (String item : columnNames) {
			params.append('"').append(item).append("\",");
		}
    	if(params.length() > 1)params.setCharAt(params.length() - 1, ']');
    	else params.append(']');
    	
    	support.addScript("LGridInsertRowCleaner.clearFields(" + params + ", '" + rowForm.getClientId() + "')");
    	
    	support.addScript("Event.observe('" + submitDelegate.getClientId() + "', " +
			"'click', " +
			"function(event){" +
			"var formManager = new LGridInsertRow( " + params + ", '" + addRowForm.getClientId() + "');" +
			"formManager.copyFields($(Event.element(event)));" +
			"formManager.submitForm();" +
			"});");

    	
//    	support.addScript("Event.observe('" + addRowButton.getClientId() + "', " +
//    			"'click', " +
//    			"function(event){" +
//    			"var formManager = new LGridInsertRow( " + params + ", '" + addRowForm.getClientId() + "');" +
//    			"formManager.copyFields($(Event.element(event)));" +
//    			"formManager.submitForm();" +
//    			"})");

    	
//    	StringBuffer params = new StringBuffer("[");
//    	for (String item : columnNames) {
//    		params.append('"').append(item).append("\",");
//    	}
//    	if(params.length() > 1)params.setCharAt(params.length() - 1, ']');
//    	else params.append(']');
//    	
//    	support.addScript("new LGridInsertRow( '" + zone + "', " + params + ", '" + zone + "_input_');");
    }
    
    boolean onSuccessFromAddRowForm(){
    	System.out.println("zzz " + addRowForm.getHasErrors());
    	resources.triggerEvent(ADD_ROW_EVENT, new Object[] {getInstance()}, null);
    	resources.triggerEvent(ADD_ROW_EVENT, new Object[] {getInstance(), addRowForm}, null);
    	resources.triggerEvent(InternalConstants.GRID_INPLACE_UPDATE, new Object[] {zone}, null);
    	return true;
    }
    boolean onFailureFromAddRowForm(){
    	System.out.println("zzz " + addRowForm.getHasErrors());
    	System.out.println("zzz " + addRowForm.getDefaultTracker().getErrors());
    	resources.triggerEvent(InternalConstants.GRID_INPLACE_UPDATE, new Object[] {zone}, null);
    	return true;
    }
	@SuppressWarnings("unchecked")
	public List<String> getColumnNames() {
		List propertyNames = gridModel.getDataModel().getPropertyNames();
		return propertyNames;
//		return propertyNames.subList(0, propertyNames.size() - 1);
	}

	public BeanModel<?> getModel() {
		return gridModel.getDataModel();
	}

	public void setColumnName(String columnName) {
		columnModel = gridModel.getDataModel().get(columnName);
	}

	public String getColumnName() {
		return columnModel.getPropertyName();
	}

	public int getColspan() {
		return gridModel.getDataModel().getPropertyNames().size();
	}
	
	public Object getInstance(){
		instance = instance != null ? instance : getModel().newInstance();;
		return instance;
	}
	
	public void setInstance(Object instance){
		this.instance = instance;
	}
	
	public String getButtonId(){
		return support.allocateClientId(resources);
	}
	
	public boolean isInError(){
		return addRowForm.getHasErrors();
	}
	
	public String getErrors(){
		return addRowForm.getDefaultTracker().getErrors().toString();
	}
	
	public Block getBlockForColumn() {
		Block override = overrides.getOverrideBlock(columnModel.getId() + "InputCell");

		if (override != null)
			return override;

		if(LGrid.REMOVE_COLUMN_NAME.equals(columnModel.getId()))return lGridRemoveCell;
		else return standardInputCell;
	}

	public Block getBlockForColumnForm() {
		Block override = overrides.getOverrideBlock(columnModel.getId() + "InputCell");
		
		if (override != null)
			return override;
		
		if(LGrid.REMOVE_COLUMN_NAME.equals(columnModel.getId()))return emptyCell;
		else return delegateInputCell;
	}
	
}
